package IHM;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.text.BadLocationException;

import org.jdom.Element;

import Controle.Controleur;
import Metier.Page;
import Metier.Paragraphe;

/**
 * Classe gerant l'affichage des elements dans la zone d'aperçu
 * @author Aubry Thomas
 * @author Bouchet Sylvain
 * @author Fauvel Alexis
 * @author Lessieur Jocelyn
 * @author Mathias Bastien 
 * @author Teuf Antoine
 * @version 1.0
 */
public class VisuElement extends JPanel implements ActionListener{
	
	/**
	 * L'instance de l'element à afficher
	 */
	private Element elem;
	
	/**
	 * L'instance de l'element parent de celui à afficher
	 */
	private Element parent;
	
	/**
	 * index de l'element dans l'arbre des elements
	 */
	private int index;
	
	/**
	 * l'instance du Visu de l'application
	 * permet de faire le lien entre l'affichage d'une element et l'affichage complet
	 */
	private Visu visu;
	
	/**
	 * Bouton permetant de remonter le l'element dans l'arbre
	 */
	private JButton prec;
	
	/**
	 * Bouton permetant de descendre l'element dans l'arbre
	 */
	private JButton suiv;
	
	/**
	 * Bouton permetant de modifier l'element
	 */
	private JButton modif;
	
	/**
	 * Bouton permetant de supprimer l'element 
	 */
	private JButton supp;
	
	/**
	 * JPanel contenant l'element
	 * @see VisuElement#getPanelPrinc()
	 */
	private JPanel panelPrinc;
	
	/**
	 * Nom de l'element
	 */
	private String nomClasse;
	
	/**
	 * L'instance IHM de l'application
	 */
	private IHM ihm;
	
	/**
	 * Constructeur de la classe VisuElement
	 * @param ihm	l'instance de l'IHM
	 * @param elem	l'instance de l'element à afficher
	 * @param num	index de l'element
	 * @param visu	l'instance de la Visu
	 */
	public VisuElement(IHM ihm, Element elem,int num,Visu visu){
		super();
		this.ihm = ihm;
		this.elem=elem;
		this.index=num;
		this.visu=visu;
		this.parent=elem.getParentElement();
		
		panelPrinc=new JPanel(new BorderLayout());
		
		JPanel panelCentral=new JPanel(new BorderLayout());//FlowLayout());

		/************************************/
		/*  Mise en place du panel du haut  */
		/************************************/
		
		JPanel haut=new JPanel();
		haut.setLayout(new BorderLayout());
		
		
		nomClasse="TitrePage"; //initialise le nom de la classe a TitrePage
		
		String s=elem.getClass().getName();//récupère le vrai nom de la classe de l'élément

		String[] tab=s.split("\\.");//découpe pour avoir juste la dernière partie
		
		//si la derniere partie récupérée est égale a élément alors on laisse TitrePage sinon on change par le nouveau nom
		if(!tab[tab.length-1].equals("Element"))
			nomClasse=tab[tab.length-1];
		
		JLabel label=new JLabel(nomClasse);
		haut.add(label);//ajout du nom de l'élément en haut
		
		
		//toolbar contenant les boutons
		JToolBar tbBoutons= new JToolBar();
		tbBoutons.setFloatable(false);//empeche de pouvoir déplacer la toolbar
		
		/***************************/
		/*  creation des bouttons  */
		/***************************/
		
		//bouton precedent
		prec=new JButton();
		prec.setToolTipText("Remonter");													//affichage du commentaire quand la souris reste sur le bouton
		prec.setIcon(new ImageIcon(getClass().getResource("/images/monter.png")));	//insertion d'une image comme arriere plan
		prec.addActionListener(this);														//gestion de l'action sur clique du bouton
		prec.setBorderPainted(false);														//enlever les contours du bouton
		
		//bouton suivant
		suiv=new JButton();
		suiv.setToolTipText("Descendre");
		suiv.setIcon(new ImageIcon(getClass().getResource("/images/descendre.png")));
		suiv.addActionListener(this);
		suiv.setBorderPainted(false);
		
		//bouton modifier
		modif=new JButton();
		modif.setToolTipText("Modifier");
		modif.setIcon(new ImageIcon(getClass().getResource("/images/modifier.png")));
		modif.addActionListener(this);
		modif.setBorderPainted(false);
		
		//bouton supprimer
		supp=new JButton();
		supp.setToolTipText("Supprimer");
		supp.setIcon(new ImageIcon(getClass().getResource("/images/supprimer.png")));
		supp.addActionListener(this);
		supp.setBorderPainted(false);
		
		//ajout des buttons a la toolbar
		tbBoutons.add(modif);
		tbBoutons.add(supp);
		tbBoutons.add(prec);
		tbBoutons.add(suiv);
		
		if(index==2)
			prec.setEnabled(false);//impossible de remonter l'élément si il juste apres le TitrePage
		if(index+2==parent.getContentSize())
			suiv.setEnabled(false);//impossible de descendre l'élément si il est en dernier
		
		if(nomClasse.equals("TitrePage")){
			supp.setEnabled(false);//on ne peut pas supprimer le TitrePage de la page
			prec.setEnabled(false);//on ne peut pas deplacer le TitrePage de la page
			suiv.setEnabled(false);//on ne peut pas deplacer le TitrePage de la page
		}
		
		//ajoute des boutons en haut a droite
		haut.add(tbBoutons,"East");
		panelPrinc.add(haut,"North");
		
			
		
		/*********************************************************/
		/* Affichage du contenu de l'element en fonction du type */
		/*********************************************************/
		JTextField text = new JTextField();
		JTextPane textPane=new JTextPane();
		String contenu="";
		if(nomClasse.equals("Image")){
			VisuImage vImg=new VisuImage(ihm.getControleur().getRacine()+"/"+((Page)(elem.getParent())).getNomProjet()+"/images/"+elem.getValue(),ihm);//affichage de l'image)
			panelCentral.add(vImg);
			panelCentral.setPreferredSize(new Dimension(panelCentral.getWidth(), vImg.getImgHeight()));
			modif.setEnabled(false);//on ne peut modifier une image
		} else if(nomClasse.equals("Lien")){
			contenu+=elem.getAttributeValue("intitule")+" ("+elem.getAttributeValue("lien")+")";
			text.setText(contenu);
			text.setEditable(false);
			text.setBackground(((Page)(elem.getParent())).getProjet().getTheme().getFond());
			panelCentral.add(text);
			modif.setEnabled(false);
		}else{
			
			if(nomClasse.equals("Paragraphe")){
				Paragraphe p=(Paragraphe)elem;
				textPane.setStyledDocument(p.getStyleDoc());
				textPane.setEditable(false);
				textPane.setBackground(((Page)(elem.getParent())).getProjet().getTheme().getFond());
				panelCentral.add(textPane);//contenu de l'élément dans le panel central
				textPane.setFont(new Font("Monospaced",Font.PLAIN,12));

				//calcul du nombre de ligne pour l'affichage
				int nbLigne=0;
				String[] ligne=textPane.getText().split("\n");//decoupage de chaque ligne
				for(int i=0; i<ligne.length;i++){
					//on ajout un nombre de ligne égale au nombre de caractère d'une ligne 
					//divisé par la largeur du visuElement divisé par 7 qui est la largeur d'un caractere
					//on ajoute 1 car si le nombre de caractère ne dépasse pas le nombre de caractère maximum sur une ligne
					//cela renvera 0 pourtant il y a bien une ligne au minimum.
					nbLigne+=(ligne[i].length()/((int)(visu.getWidth()*0.8)/7))+1;
				}
				//on redéfini la taille du panelCentral surtout pour la hauteur qui est égale au nombre de ligne 
				//multiplié par 15 qui est la hauteur d'une ligne.
				panelCentral.setPreferredSize(new Dimension(panelCentral.getWidth(),nbLigne*15));
			}
			else{
				contenu+=elem.getValue();
				text.setText(contenu);
				text.setEditable(false);
				text.setBackground(((Page)(elem.getParent())).getProjet().getTheme().getFond());
				panelCentral.add(text);//contenu de l'élément dans le panel central
			}
			
			
		}
		
		//ajout du panel central au panel principal
		panelPrinc.add(panelCentral);
		add(panelPrinc);
		Color couleurFond, couleurSsTitre, couleurTitrePage, couleurPara,couleurLien,couleurTitre;
		couleurFond = couleurTitre= couleurSsTitre= couleurTitrePage = couleurPara = couleurLien= visu.getColorDefaut();
		//gestion des couleurs des visuElements, de l'alignement du texte et de la taille du texte
		if(visu.getIhm().getControleur().getProjetEnCours()!=null) {
			couleurFond = visu.getIhm().getControleur().getProjetEnCours().getTheme().getFond();
			couleurTitre= visu.getIhm().getControleur().getProjetEnCours().getTheme().getTitre();
			couleurSsTitre = visu.getIhm().getControleur().getProjetEnCours().getTheme().getSousTitre();
			couleurTitrePage = visu.getIhm().getControleur().getProjetEnCours().getTheme().getTitrePage();
			couleurPara = visu.getIhm().getControleur().getProjetEnCours().getTheme().getParagraphe();
			couleurLien = visu.getIhm().getControleur().getProjetEnCours().getTheme().getLien();
			
		}
		setBackground(couleurFond);
		panelPrinc.setBackground(couleurFond);
		panelCentral.setBackground(((Page)(elem.getParent())).getProjet().getTheme().getFond());
		panelPrinc.setBorder(BorderFactory.createLineBorder(label.getBackground()));
		
		if(nomClasse.equals("TitrePage")){
			text.setBorder(BorderFactory.createLineBorder(panelPrinc.getBackground())); 				//supprime la bordure du jtextfield
			text.setFont(new Font("Arial",Font.PLAIN,30));												//met le texte en arial et de taille 30
			text.setForeground(couleurTitrePage);	//met la couleur du texte
			text.setHorizontalAlignment(JTextField.CENTER);												//centre le texte
		}
		else if(nomClasse.equals("Titre")){
			text.setBorder(BorderFactory.createLineBorder(panelPrinc.getBackground())); 				//supprime la bordure du jtextfield
			text.setFont(new Font("Arial",Font.PLAIN,20));												//met le texte en arial et de taille 30
			text.setForeground(couleurTitre);	//met la couleur du texte
			text.setHorizontalAlignment(JTextField.LEFT);												//centre le texte
		}
		else if(nomClasse.equals("SousTitre")){
			text.setBorder(BorderFactory.createLineBorder(panelPrinc.getBackground())); 				//supprime la bordure du jtextfield
			text.setFont(new Font("Arial",Font.PLAIN,15));												//met le texte en arial et de taille 30
			text.setForeground(couleurSsTitre);	//met la couleur du texte
			text.setHorizontalAlignment(JTextField.LEFT);												//centre le texte
		}
		else if(nomClasse.equals("Lien")){
			text.setBorder(BorderFactory.createLineBorder(panelPrinc.getBackground()));
			text.setForeground(couleurLien);
		}
		else if(nomClasse.equals("Paragraphe"))	textPane.setForeground(couleurPara);
		else if(nomClasse.equals("Image"))		panelCentral.setBackground(couleurFond);
		
		
		
		//redimensionne le visu élément en fonction de la largeur de l'écran
		
		panelPrinc.setPreferredSize(new Dimension((int)(visu.getWidth()*0.8),(int)getPreferredSize().getHeight()));
		
		
	}
	
	/**
	 * Permet de recuperer le panel prrincipal
	 * @return	une instance JPanel contenant le panel principale
	 */
	public JPanel getPanelPrinc() {
		return panelPrinc;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==supp){
			parent.removeContent(index+1);	//suppression de l'élément vide placé aprés l'élément courant
			if(nomClasse.equals("Image")){
				File delFile=new File(ihm.getControleur().getRacine()+"/"+((Page)parent).getNomProjet()+"/images/"+elem.getText());
				System.gc();
				delFile.delete();
			}
			if(nomClasse.equals("Lien") && !elem.getText().startsWith("http://") && !elem.getText().startsWith("https://")){
				File delFile=new File(ihm.getControleur().getRacine()+"/"+((Page)parent).getNomProjet()+"/"+elem.getAttributeValue("lien"));
				System.gc();
				delFile.delete();
			}
			parent.removeContent(elem);		//suppression de cet élément
			visu.maj();
		}
		if(e.getSource()==modif){
			if(nomClasse.equals("TitrePage")) {
				boolean existe;
				String res=null;
				do{
					existe=false;
					res = JOptionPane.showInputDialog(this, "Modification du "+nomClasse,elem.getValue());
					if(res!=null && res.isEmpty()){
						JOptionPane.showMessageDialog(this, "Veuillez remplir le champ");
					}
					else if(res!=null){
		        		for(Page p:visu.getPage().getProjet().getPages()){
		       				if(res.equals(p.getTitrePage()))
		      					existe=true;
		       			}
		       			if(existe){
		       				JOptionPane.showMessageDialog(this, "Une page de ce titre existe déjà dans votre projet");
		       			}
		       			else{
		       				elem.setText(res);
							visu.maj();
							visu.getIhm().majArbre();
		       			}
					}
				}
				while(existe && res!=null);	
			}else if(nomClasse.equals("SousTitre") || nomClasse.equals("Titre")){
				String res = JOptionPane.showInputDialog(this, "Modification du "+nomClasse,elem.getValue());
				if(res!=null){
					elem.setText(res);
					visu.maj();
				}
			}
			else if(nomClasse.equals("Paragraphe")){
				visu.getIhm().getZoneTexte().setCommentaire(false);
				visu.getIhm().setToolBarModif(elem);
			}
		}
		if(e.getSource()==prec){
			//Entre chanque élément il y a un élément vide pour les sauts de ligne
			//il faut donc déplacer deux éléments a l'index et l'index-1
			parent.addContent(index,parent.removeContent(index-2));
			parent.addContent(index-1,parent.removeContent(index-2));

			visu.maj();
		}
		if(e.getSource()==suiv){
			//Entre chanque élément il y a un élément vide pour les sauts de ligne
			//il faut donc déplacer deux éléments a l'index et l'index+1
			parent.addContent(index,parent.removeContent(index+2));
			parent.addContent(index+1,parent.removeContent(index+2));

			visu.maj();
		}
	}
}
